package com.youlin.untils;

import com.madgag.gif.fmsware.AnimatedGifEncoder;
import com.madgag.gif.fmsware.GifDecoder;
import net.coobird.thumbnailator.Thumbnails;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;

public class MakeOver {

    public static void main(String[] args) {

        createGIF("456.gif","Beckham.png","2.png",182,55);

    }

    /**
     * 合成 gif
     * @param outputFileName
     * @param path1
     * @param path2
     * @param height
     * @param weidth
     */
    public static void createGIF(String outputFileName, String path1, String path2, int height, int weidth){
        try {
            GifDecoder decoder = new GifDecoder();
            decoder.read("123.gif");

            // 指定Frame的文件
            AnimatedGifEncoder e = new AnimatedGifEncoder();
            OutputStream os = new FileOutputStream(outputFileName); //输出图片
            e.start(os);// 开始处理
            e.setQuality(10); //设置图片质量
            e.setRepeat(999);  //设置循环
            e.setDelay(0); // 设置延迟时间

//            e.setTransparent(Color.WHITE);
            e.setTransparent(new Color(0, 0, 0, 0));
            e.setBackground(new Color(0,0,0,0));

            for (int i = 0; i < decoder.getFrameCount(); i++) {
                BufferedImage image = decoder.getFrame(i);
//                ImageIO.write(image, "png", new File("gif"+i+".png"));

//                BufferedImage im = pressImage(path1, image, weidth, height);

                //可以加入对图片的处理，比如缩放，压缩质量
                e.addFrame(pic(image));

                if (i % 2 == 0) System.out.printf("\033[34m %s \n", i);
                else System.out.printf("\033[31m %s \n", i);
            }
            e.finish();
        } catch (Exception e) {
            System.out.println(e);
            e.printStackTrace();
        }
    }

    /**
     * 叠加图片
     * @param pressImg
     * @param targetImg
     * @param x
     * @param y
     * @return
     */
    public static BufferedImage pressImage(String pressImg, BufferedImage targetImg, int x, int y) {
        try {
            // 目标文件
//            File _file = new File(targetImg);
//            Image src = ImageIO.read(_file);
            int wideth = targetImg.getWidth(null);
            int height = targetImg.getHeight(null);
//            BufferedImage image = new BufferedImage(wideth, height, BufferedImage.TYPE_INT_RGB);
            BufferedImage image = new BufferedImage(wideth, height, BufferedImage.TYPE_4BYTE_ABGR);
//            Graphics g = image.createGraphics();
            Graphics2D g = (Graphics2D) image.getGraphics();
            // 水印文件
            File _filebiao = new File(pressImg);
            Image src_biao = ImageIO.read(_filebiao);
            int wideth_biao = src_biao.getWidth(null);
            int height_biao = src_biao.getHeight(null);
//            g.drawImage(src_biao, x, y, wideth_biao, height_biao, null);
            g.drawImage(targetImg, 0, 0, wideth, height, null);
            // 水印文件结束
            g.dispose();
            return image;
        } catch (Exception e) {
            System.out.println(e);
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 透明背景抠图
     * @param bi
     * @return
     */
    public static BufferedImage pic(BufferedImage bi) {
        ImageIcon imageIcon = new ImageIcon(bi);
        BufferedImage bufferedImage = new BufferedImage(imageIcon.getIconWidth(),
                imageIcon.getIconHeight(), BufferedImage.TYPE_4BYTE_ABGR);
        Graphics2D g2D = (Graphics2D) bufferedImage.getGraphics();
        g2D.setColor(Color.WHITE);
        g2D.drawImage(imageIcon.getImage(), 0, 0, imageIcon.getImageObserver());
        int alpha = 0;
        for (int j1 = bufferedImage.getMinY(); j1 < bufferedImage.getHeight(); j1++) {
            for (int j2 = bufferedImage.getMinX(); j2 < bufferedImage.getWidth(); j2++) {
                int rgb = bufferedImage.getRGB(j2, j1);

                int R = (rgb & 0xff0000) >> 16;
                int G = (rgb & 0xff00) >> 8;
                int B = (rgb & 0xff);

                if (R < 60 && G < 20 && B < 10) {
                    rgb = ((alpha + 1) << 24) | (rgb & 0x00ffffff);
                }

                bufferedImage.setRGB(j2, j1, rgb);
            }
        }
        g2D.drawImage(bufferedImage, 0, 0, imageIcon.getImageObserver());
        return bufferedImage;
    }

    /**
     * 测试生产透明背景gif
     */
    public static void testGif () {
        AnimatedGifEncoder encoder = new AnimatedGifEncoder();
        encoder.start("out.gif");
        encoder.setTransparent(Color.WHITE);
        encoder.setRepeat(0);
        encoder.setDelay(30);

        BufferedImage img = new BufferedImage(200, 200, BufferedImage.TYPE_3BYTE_BGR);
        Graphics2D g2d = img.createGraphics();

        for (int i=0; i<100; i++) {
            g2d.setColor(Color.WHITE);
            g2d.fillRect(0, 0, 200, 200);
            g2d.setColor(Color.BLACK);
            g2d.drawOval(0, i, 100, 100);

            encoder.addFrame(img);
        }

        g2d.dispose();
        encoder.finish();
    }

    /**
     * 根据指定大小压缩图片
     * @param imageBytes  源图片字节数组
     * @param desFileSize 指定图片大小，单位kb
     * @return 压缩质量后的图片字节数组
     */
    public static byte[] compressPicForScale(byte[] imageBytes, double desFileSize) {
        if (imageBytes == null || imageBytes.length <= 0 || imageBytes.length < desFileSize * 1024) {
            return imageBytes;
        }
        long srcSize = imageBytes.length;
        double accuracy = getAccuracy(srcSize / 1024);
        try {
            while (imageBytes.length > desFileSize * 1024) {
                ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream(imageBytes.length);
                Thumbnails.of(inputStream)
                        .scale(accuracy)
                        .outputQuality(accuracy)
                        .toOutputStream(outputStream);
                imageBytes = outputStream.toByteArray();
            }
        } catch (Exception e) {
        }
        return imageBytes;
    }

    /**
     * 自动调节精度(经验数值)
     * @param size 源图片大小
     * @return 图片压缩质量比
     */
    private static double getAccuracy(long size) {
        double accuracy;
        if (size < 900) {
            accuracy = 0.85;
        } else if (size < 2047) {
            accuracy = 0.6;
        } else if (size < 3275) {
            accuracy = 0.44;
        } else {
            accuracy = 0.4;
        }
        return accuracy;
    }

    /**
     * 把一个文件转化为byte字节数组
     * @param file
     * @return
     */
    private static byte[] fileConvertToByteArray(File file) {
        byte[] data = null;
        try {
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int len;
            byte[] buffer = new byte[1024];
            while ((len = fis.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }

            data = baos.toByteArray();
            fis.close();
            baos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }

    /**
     * 将Byte数组转换成文件
     * @param bytes
     * @param filePath
     * @param fileName
     */
    public static void getFileByBytes(byte[] bytes, String filePath, String fileName) {
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file = null;
        try {
            File dir = new File(filePath);
            if (!dir.exists()) {// 判断文件目录是否存在
                dir.mkdirs();
            }
            file = new File(filePath + fileName);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(bytes);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 测试压缩
     */
    public static void testCompress () {
        File file = new File("Beckham.png");
        byte[] bytes = fileConvertToByteArray(file);
        byte[] bytes1 = compressPicForScale(bytes, 30);
        getFileByBytes(bytes1, "", "Beckham7.png");
    }

}
